﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSLib.Parsing.Lua.ObjectModel;

namespace PSLib.Parsing.Lua.ObjectModel
{
    public class Metatable : IEnumerable<KeyValuePair<string, Variable>>
    {
        #region Constructor

        public Metatable()
        {
            this.members = new Dictionary<string, Variable>();
            lastMemberIndex = 0;
        }

        #endregion

        #region Public methods

        public bool Contains(string key)
        {
            return members.ContainsKey(key);
        }

        public bool Contains(int index)
        {
            return Contains(ConvertKey(index));
        }

        internal void AddRange(IEnumerable<Variable> variables)
        {
            foreach (var item in variables)
            {
                if (item != null && item.Name != "_") this[item.Name] = item;
            }
        }

        #endregion

        #region Private methods

        internal static string ConvertKey(int index)
        {
            return "__" + index.ToString();
        }

        #endregion

        #region Properties

        public Variable this[string key]
        {
            get
            {
                Variable result = null;
                if (members.ContainsKey(key)) result = members[key];
                return result;
            }
            set
            {
                if (value != null)
                {
                    if(value.Name == Variable.UnknownIndexName)
                    {
                        key = ConvertKey(++lastMemberIndex);
                        value.Name = key;
                    }
                    else if (value.Name == Variable.AutoAsignName)
                    {
                        value.Name = key;
                    }
                }
                
                if (!members.ContainsKey(key)) members.Add(key, null);
                members[key] = value;
            }
        }
        public Variable this[int index]
        {
            get
            {
                if (lastMemberIndex < index) lastMemberIndex = index;
                return this[ConvertKey(index)];
            }
            set
            {
                this[ConvertKey(index)] = value;
            }
        }

        #endregion

        #region IEnumerable implementation

        public IEnumerator<KeyValuePair<string, Variable>> GetEnumerator()
        {
            return members.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return members.GetEnumerator();
        }

        #endregion

        private Dictionary<string, Variable> members;
        private int lastMemberIndex;
    }
}
